package com.chujian.framework.starter.async;

import com.chujian.framework.constant.ThreadConst;
import com.chujian.framework.util.ErvUs;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author ：yj
 * @date ：2020-12-09
 * 异步线程池自动装配
 */
@EnableAsync(proxyTargetClass = true)
@Configuration
public class AsyncAutoConfiguration {

    /**
     * 核心线程池装配
     * <p>
     * 用于执行核心、耗时较短的逻辑
     *
     * @return
     */
    @Bean(ThreadConst.CORE_EXECUTOR)
    public TaskExecutor coreExecutor() {

        int cpuProcessors = ErvUs.getCpuProcessors();

        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(cpuProcessors * 2); // 核心线程数
        taskExecutor.setMaxPoolSize(cpuProcessors * 5); // 最大线程数
        taskExecutor.setQueueCapacity(100000); // 队列容量
        taskExecutor.setKeepAliveSeconds(200); // 200秒后空闲线程释放
        taskExecutor.setThreadNamePrefix("chujian-core-");

        // 重新添加当前任务
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.initialize();
        return taskExecutor;
    }

    /**
     * cache线程池，类似 java 的 Executors.newCachedThreadPool()
     * <p>
     * 用于执行小而多的任务
     *
     * @return
     */
//    @Bean(ThreadConst.CACHE_EXECUTOR)
    public ThreadPoolTaskExecutor cacheExecutor() {

        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 缺省参数
//        int corePoolSize = 1;
//        int maxPoolSize = 2147483647;
//        int keepAliveSeconds = 60;
//        int queueCapacity = 2147483647;

        taskExecutor.setCorePoolSize(4); // 核心线程数
        taskExecutor.setThreadNamePrefix("chujian-cache-");
        // 重新添加当前任务
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.initialize();
        return taskExecutor;
    }

}
